import { currentTime } from '../core/SimulationClock'
import Product from './Product'
import { getReadyProduct } from '../core/ReadyProducts'
import { StationStatus } from '../types'
import { dispatcher } from '../core/Dispatcher'

abstract class BaseStation {
  id: string
  name: string
  x: number
  y: number
  width: number
  height: number
  prevStations: BaseStation[] = []
  nextStations: BaseStation[] = []
  status: StationStatus = 'idle'
  readyProduct: null | string = null

  constructor(id: string, name: string, x: number, y: number, width = 100, height = 100) {
    this.id = id
    this.name = name
    this.x = x
    this.y = y
    this.width = width
    this.height = height
  }

  //设置下游设备
  setNextStations(stations: BaseStation[]) {
    this.nextStations = stations
  }

  //设置上游设备
  setPrevStations(stations: BaseStation[]) {
    this.prevStations = stations
  }

  //接受就绪产品
  receiveReadyProduct(productId: string): void {
    if (this.status === 'idle') {
      this.readyProduct = productId
      this.setStatus('ready')

      const product = getReadyProduct(productId)
      if (!product) {
        this.setStatus('idle')
        console.log(`[${currentTime}] ❌ ${productId} 没有发现该产品`)
        return
      }
      console.log(`[${currentTime}] ${product.id} 已到达 --> ${this.name}`)
      product.setFrom(this.id)
      this.onProductReceived(product)
    } else {
      console.log(`[${currentTime}] ${this.id} 不在空闲状态, 无法接受产品 ${productId}`)
    }
  }

  // 子类必须实现
  public abstract canReceiveProduct(id: string, product: Product): boolean
  protected abstract onProductReceived(product: Product): void
  public abstract tryDispatchCurrentProduct(): void

  protected setStatus(newStatus: StationStatus) {
    if (this.status !== newStatus) {
      this.status = newStatus
      dispatcher.notifyStatusChange(this, newStatus)
    }
  }

  /**
   * 外部调用本部事件，需要通过一个事件总线来通知
   */
  public eventWindow(eventType: 'status' | 'rework' | 'delProduct', param: any): void {
    return
  }
}

export default BaseStation
